use actix_web::web::{Data, Json, Query};

use crate::{
    common::{
        app::tags::MENU,
        types::{ApiListResult, ApiResult},
    },
    config::{auth::AuthInfo, state::AppState},
    models::{
        request::{
            common_request::IdRequest,
            menu_req::{MenuCreate, MenuUpdate},
        },
        response::menu_res::{MenuDetail, MenuListInfo},
    },
    services::menu_service as MenuService,
};

/// 新增菜单
#[utoipa::path(
    tags = [MENU],
    post,
    path = "/api/v1/menu/create",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = MenuCreate
)]
pub async fn create(
    state: Data<AppState>,
    req: Json<MenuCreate>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    MenuService::create(state, req.into_inner(), auth_info).await
}

/// 删除菜单
#[utoipa::path(
    tags = [MENU],
    post,
    path = "/api/v1/menu/delete",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = IdRequest
)]
pub async fn delete(
    state: Data<AppState>,
    req: Json<IdRequest>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    MenuService::delete(state, req.into_inner(), auth_info).await
}

/// 修改菜单
#[utoipa::path(
    tags = [MENU],
    post,
    path = "/api/v1/menu/update",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = MenuUpdate
)]
pub async fn update(
    state: Data<AppState>,
    req: Json<MenuUpdate>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    MenuService::update(state, req.into_inner(), auth_info).await
}

/// 菜单详情
#[utoipa::path(
    tags = [MENU],
    get,
    path = "/api/v1/menu/detail",
    responses(
        (status = 200, description = "Ok", body = MenuDetail),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = IdRequest
)]
pub async fn detail(
    state: Data<AppState>,
    req: Query<IdRequest>,
    auth_info: AuthInfo,
) -> ApiResult<MenuDetail> {
    MenuService::detail(state, req.into_inner(), auth_info).await
}

/// 菜单列表
#[utoipa::path(
    tags = [MENU],
    get,
    path = "/api/v1/menu/list",
    responses(
        (status = 200, description = "Ok", body = MenuDetail),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
)]
pub async fn list(state: Data<AppState>, auth_info: AuthInfo) -> ApiListResult<MenuListInfo> {
    MenuService::list(state, auth_info).await
}
